package com.eduagent.xwqeduagent.api.DocumentTranslation;

import com.eduagent.xwqeduagent.api.DocumentTranslation.api.DocumentTranslationApi;
import com.eduagent.xwqeduagent.api.DocumentTranslation.api.DocumentTranslationApiImpl;
import com.eduagent.xwqeduagent.api.DocumentTranslation.constant.DocumentTranslationConstant;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentInfo;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentTranslationLanguage;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentTranslationRequest;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentTranslationResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * Client for document translation
 */
@Slf4j
@Component
public class DocumentTranslationClient {

    private final DocumentTranslationApi api;

    /**
     * Constructor
     *
     * @param apiKey API key
     * @param appId Application ID
     */
    public DocumentTranslationClient(@Value("${niutrans.document.apiKey}") String apiKey, 
                                    @Value("${niutrans.document.appId}") String appId) {
        this.api = new DocumentTranslationApiImpl(apiKey, appId);
    }

    /**
     * Upload and translate a file
     *
     * @param request Document translation request
     * @return File number if successful
     */
    public String uploadAndTranslate(DocumentTranslationRequest request) {
        try {
            DocumentTranslationResponse response = api.uploadAndTranslate(
                    request.getFrom(),
                    request.getTo(),
                    request.getFile(),
                    request.getRealmCode(),
                    request.getTermId(),
                    request.getMemoryId(),
                    request.getProcessingMode()
            );

            if (response.getCode() == 200 && response.getData() != null) {
                // Extract fileNo from response
                return response.getData().toString().replaceAll(".*\"fileNo\":\\s*\"([^\"]+)\".*", "$1");
            } else {
                log.error("Error uploading and translating file: {}", response.getMsg());
                return null;
            }
        } catch (Exception e) {
            log.error("Error uploading and translating file: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * Get document information and translation status
     *
     * @param fileNo File number
     * @return Document information
     */
    public DocumentInfo getDocumentInfo(String fileNo) {
        return api.getDocumentInfo(fileNo);
    }

    /**
     * Interrupt/terminate a translation
     *
     * @param fileNo File number
     * @return True if terminated successfully, false otherwise
     */
    public boolean interruptTranslation(String fileNo) {
        return api.interruptTranslation(fileNo);
    }

    /**
     * Download translated file
     *
     * @param fileNo File number
     * @param type Download type (0: source, 1: translation, 2: bilingual, etc.)
     * @param savePath Path to save the downloaded file
     * @return True if download is successful, false otherwise
     */
    public boolean downloadFile(String fileNo, Integer type, String savePath) {
        return api.downloadFile(fileNo, type, savePath);
    }

    /**
     * Download translated file with default type (translated file)
     *
     * @param fileNo File number
     * @param savePath Path to save the downloaded file
     * @return True if download is successful, false otherwise
     */
    public boolean downloadTranslatedFile(String fileNo, String savePath) {
        return api.downloadFile(fileNo, DocumentTranslationConstant.DownloadType.TRANSLATED, savePath);
    }

    /**
     * Get download URL for translated file
     *
     * @param fileNo File number
     * @param type Download type (0: source, 1: translation, 2: bilingual, etc.)
     * @return Download URL
     */
    public String getDownloadUrl(String fileNo, Integer type) {
        return api.getDownloadUrl(fileNo, type);
    }

    /**
     * Get download URL for translated file with default type (translated file)
     *
     * @param fileNo File number
     * @return Download URL
     */
    public String getTranslatedFileUrl(String fileNo) {
        return api.getDownloadUrl(fileNo, DocumentTranslationConstant.DownloadType.TRANSLATED);
    }

    /**
     * Delete a file
     *
     * @param fileNo File number
     * @return True if deleted successfully, false otherwise
     */
    public boolean deleteFile(String fileNo) {
        return api.deleteFile(fileNo);
    }

    /**
     * Wait for translation to complete
     *
     * @param fileNo File number
     * @param pollingIntervalMs Interval between status checks in milliseconds
     * @param timeoutMs Maximum time to wait in milliseconds
     * @return Document information if translation completed, null if timed out or failed
     */
    public DocumentInfo waitForTranslation(String fileNo, long pollingIntervalMs, long timeoutMs) {
        long startTime = System.currentTimeMillis();
        DocumentInfo info = null;
        
        while (System.currentTimeMillis() - startTime < timeoutMs) {
            info = getDocumentInfo(fileNo);
            
            if (info == null) {
                // Error getting status
                log.error("Error getting translation status for file {}", fileNo);
                return null;
            }
            
            // Check if translation is complete
            if (info.getTransStatus() == DocumentTranslationConstant.TranslationStatus.SUCCESS) {
                log.info("Translation completed successfully for file {}", fileNo);
                return info;
            } else if (info.getTransStatus() == DocumentTranslationConstant.TranslationStatus.FAILURE) {
                log.error("Translation failed for file {}: {}", fileNo, info.getTransFailureCause());
                return info;
            } else if (info.getTransStatus() == DocumentTranslationConstant.TranslationStatus.TERMINATED) {
                log.warn("Translation was terminated for file {}", fileNo);
                return info;
            }
            
            // Still in progress, wait and retry
            log.debug("Translation in progress for file {}: status={}, progress={}", 
                    fileNo, info.getTransStatus(), info.getProgress());
            
            try {
                Thread.sleep(pollingIntervalMs);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("Interrupted while waiting for translation to complete");
                return info;
            }
        }
        
        log.warn("Timed out waiting for translation to complete for file {}", fileNo);
        return info;
    }
} 